<!-- 广告管理 -->
<template>
  <div>
    <el-header>
      <el-space wrap>
        <el-select
          v-model="initConfig.status"
          clearable
          placeholder="请选择广告状态"
        >
          <el-option
            v-for="item in options.status"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-select
          v-model="initConfig.type"
          clearable
          placeholder="请选择广告类型"
        >
          <el-option
            v-for="item in options.type"
            :key="item.value"
            :label="item.name"
            :value="item.value"
          />
        </el-select>
        <el-button type="primary" :icon="Search" @click="debounce(initData)"
          >查找</el-button
        >
        <el-button
          type="primary"
          :icon="Plus"
          @click="
            () => {
              title = '创建';
              dialogShow = true;
              resetData();
            }
          "
          v-btn="'promotion:advert:create'"
          >添加</el-button
        >
      </el-space>
    </el-header>
    <el-container v-loading="loadingA">
      <!-- 列表 -->
      <el-table :data="advertData" border align="center">
        <el-table-column prop="id" label="广告ID" align="center" width="90" />
        <el-table-column prop="title" label="广告标题" align="center" />
        <el-table-column label="广告图片" align="center" width="140">
          <template #default="scope">
            <el-popover
              placement="right"
              :width="250"
              trigger="hover"
              v-if="scope.row.type < 6"
            >
              <template #reference>
                <el-image style="height: 35px" :src="scope.row.imgUrl" />
              </template>
              <el-image style="width: 100%" :src="scope.row.imgUrl" />
            </el-popover>
            <el-tag type="info" v-else>类型无需图片</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="广告类型" align="center" width="150">
          <template #default="scope">
            <el-tag>{{
              options.type.find((item) => item.value == scope.row.type)?.name
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="广告状态" align="center" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status ? 'success' : 'danger'">{{
              scope.row.status ? "激活" : "冻结"
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联类型" align="center" width="100">
          <template #default="scope">
            <el-tag>{{
              options.unionType.find(
                (item) => item.value == scope.row.unionType
              )?.name
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联值[ID]" align="center">
          <template #default="scope">
            {{ scope.row.unionValue }}
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center">
          <template #default="scope">
            {{ new Date(scope.row.gmtCreate).computeDate() }}
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="200">
          <template #default="scope">
            <el-button
              type="primary"
              @click="editData(scope.row)"
              v-btn="'promotion:advert:edit'"
              >编辑</el-button
            >
            <el-button
              type="danger"
              @click="daleAdvert(scope.row)"
              v-btn="'promotion:advert:delete'"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 弹窗 -->
      <el-dialog
        v-model="dialogShow"
        :title="title"
        width="700px"
        destroy-on-close
      >
        <el-form
          ref="formRef"
          :model="dialogFrom"
          :rules="rules"
          :label-width="100"
          status-icon
        >
          <el-form-item label="广告标题" prop="title">
            <el-input v-model.trim="dialogFrom.title" type="text" />
          </el-form-item>
          <el-form-item label="广告类型" prop="type">
            <el-select
              v-model="dialogFrom.type"
              placeholder="请选择"
              @change="dialogFrom.unionType = null"
            >
              <el-option
                v-for="item in options.type"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            label="广告图片"
            prop="imgUrl"
            id="img_box"
            :style="'background:' + dialogFrom.color"
            v-if="showImg"
          >
            <el-upload
              class="avatar-uploader"
              @change="progress"
              :auto-upload="false"
              :show-file-list="false"
            >
              <img
                v-if="dialogFrom.imgUrl"
                :src="dialogFrom.imgUrl"
                style="height: 150px"
              />
              <el-icon v-else class="avatar-uploader-icon">
                <Plus />
              </el-icon>
            </el-upload>
          </el-form-item>
          <el-form-item label="广告状态" prop="status">
            <el-switch
              v-model="dialogFrom.status"
              :active-value="1"
              :inactive-value="0"
              class="ml-2"
              style="
                --el-switch-on-color: #13ce66;
                --el-switch-off-color: #ff4949;
              "
            />
          </el-form-item>
          <el-form-item label="关联类型" prop="unionType">
            <el-select
              v-model="dialogFrom.unionType"
              :placeholder="
                dialogFrom.type ? '点击时跳转目标' : '请先选择广告类型'
              "
              @change="dialogFrom.unionValue = ''"
            >
              <el-option
                v-for="item in options.unionType"
                :disabled="switchUnionType(item.value)"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="dialogFrom.unionType == 1"
            label="商品"
            prop="unionValue"
          >
            <el-cascader
              v-model="dialogFrom.unionValue"
              :props="propsA"
              placeholder="关联至商品"
              :options="suBigList"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item
            v-else-if="dialogFrom.unionType == 2"
            label="类目"
            prop="unionValue"
          >
            <el-cascader
              v-model="dialogFrom.unionValue"
              :props="propsB"
              placeholder="关联至类目"
              :options="categorytList"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item
            v-else-if="dialogFrom.unionType == 3"
            label="关键字"
            prop="unionValue"
          >
            <el-input v-model.trim="dialogFrom.unionValue" type="text" />
          </el-form-item>
          <el-form-item
            v-else-if="dialogFrom.unionType == 4"
            label="功能页面"
            prop="unionValue"
          >
            <el-select
              v-model="dialogFrom.unionValue"
              placeholder="请选择一个功能页面"
            >
              <el-option
                v-for="item in options.featurePage"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-form>
        <template #footer>
          <span>
            <el-button @click="dialogShow = false">取消</el-button>
            <el-button type="primary" @click="submitForm('formRef')"
              >确定</el-button
            >
          </span>
        </template>
      </el-dialog>
    </el-container>
    <el-footer>
      <!-- 分页组件 -->
      <paging v-bind="pageInfo" @changeReq="changeConfig"></paging>
    </el-footer>
  </div>
</template>

<script>
import Cookie from "js-cookie";
import { post, upload } from "@/utils/http";
import { Search, Plus } from "@element-plus/icons-vue";
import Paging from "@/components/paging/Paging";
import { colorImg } from "@/utils/color";
export default {
  setup() {
    return {
      Search,
      Plus,
    };
  },
  components: { Paging, Plus },
  data() {
    //4种广告关联类型
    const adUnionTypeMap = [
      { value: 1, name: "商品" },
      { value: 2, name: "类目" },
      { value: 3, name: "关键字" },
      { value: 4, name: "功能页面" },
    ];
    //6种广告类型
    const adTypeMap = [
      { value: 1, unionTypes: [1, 2, 3, 4], picRequire: true, name: "轮播" },
      { value: 2, unionTypes: [2], picRequire: true, name: "分类精选" },
      { value: 3, unionTypes: [1, 2, 3, 4], picRequire: true, name: "横幅" },
      {
        value: 4,
        unionTypes: [1, 2, 3, 4],
        picRequire: true,
        name: "首页轮播下5按钮",
      },
      { value: 6, unionTypes: [1, 2, 3, 4], picRequire: false, name: "公告" },
      { value: 9, unionTypes: [1], picRequire: false, name: "商品推荐" },
    ];
    //广告状态
    const adStatusMap = [
      { value: 0, label: "冻结" },
      { value: 1, label: "激活" },
    ];
    //功能页面
    const functionPages = [
      { value: "/pages/product/groupshop", name: "团购列表" },
      { value: "/pages/couponst", name: "优惠券列表" },
    ];
    return {
      advertData: [], //表格数据
      dialogShow: false, //是否显示弹出框
      title: "", //弹窗框的标题
      token: "", //管理员请求头
      loadingA: true, //加载表格
      // 页面加载的请求数据
      initConfig: {
        _gp: "admin.advert",
        _mt: "list",
        status: null,
        type: null,
      },
      // 添加修改的数据
      dialogFrom: {},
      // 传给分页组件的数据
      pageInfo: {
        page: 1, //跳转页数
        limit: 10, //显示条数
        total: 0,
      },
      categorytList: [], //类目配置数据
      suBigList: [], //商品配置数据
      // 下拉框的配置
      options: {
        status: adStatusMap,
        type: adTypeMap,
        unionType: adUnionTypeMap,
        featurePage: functionPages,
      },
      // 表单验证的规则
      rules: {
        title: [{ required: true, message: "请输入广告标题" }], // ---广告标题
        type: [
          { required: true, message: "请输入广告类型", trigger: "change" },
        ], // ---广告类型
        status: [{ required: true, message: "" }], // ---广告状态
        imgUrl: [{ required: true, message: "请提交图片" }], // ---图片
        unionType: [
          { required: true, message: "请选择关联类型", trigger: "change" },
        ], // ---广告关联类型
        unionValue: [
          {
            required: true,
            message: "请选择一个(商品、类目、页面等具体值)",
            trigger: "change",
          },
        ], // ---广告关联类型值
      },
      // 商品级联选择器的配置
      propsA: {
        label: "label",
        children: "children",
        value: "id",
        emitPath: false,
      },
      // 类目级联选择器的配置
      propsB: {
        label: "title",
        children: "childrenList",
        value: "id",
        emitPath: false,
      },
    };
  },
  methods: {
    // 获取商品和类目数据的方法
    getTree() {
      post({ _gp: "admin.category", _mt: "categoryTree" }).then((res) => {
        if (200 == res.errno) {
          //成功状态码
          // console.log(res.data);
          this.categorytList = res.data;
        }
      });
      post({ _gp: "admin.product", _mt: "getSpuBigTree" }).then((res) => {
        if (200 == res.errno) {
          //成功状态码
          // console.log(res.data);
          this.suBigList = res.data;
        }
      });
      this.token = { AdminToken: Cookie.get("token") }; //获取token
    },
    // 分页触发的数据改变
    changeConfig(data) {
      let { page: pageNo, limit } = data;
      Object.assign(this.initConfig, { pageNo, limit });
      this.initData();
    },
    // 初始化
    initData() {
      post(this.initConfig).then((res) => {
        if (200 == res?.errno) {
          // console.log(res.data)
          this.advertData = res.data.items;
          this.pageInfo.total = res.data.total; //获取总条数
          this.loadingA = false;
        }
      });
    },
    // 删除广告
    daleAdvert(row) {
      ElMessageBox.confirm("是否删除该广告?", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          post({
            _gp: "admin.advert",
            _mt: "delete",
            adId: row.id,
            type: row.type,
          }).then((res) => {
            if (200 == res.errno) {
              ElMessage.success("删除成功");
              this.initData();
            }
          });
        })
        .catch(() => {
          ElMessage.info("删除取消");
        });
    },
    // 关联类型判断是否禁用
    switchUnionType(value) {
      let type = this.dialogFrom.type; //获取表单中类型
      if (!type) return true;
      let unionTypes = this.options.type.find(
        (i) => i.value == type
      ).unionTypes; //获取不禁用关联类型的数组
      if (unionTypes.indexOf(value) == -1) return true;
      return false;
    },
    // 重置表单数据
    resetData() {
      this.dialogFrom = {
        _gp: "admin.advert",
        _mt: "",
        title: "", //广告标题
        type: null, //类型
        imgUrl: "", //广告图片地址
        color: "", //图片均颜色
        status: 1, //广告状态
        unionType: null, //关联类型
        unionValue: "", //关联值
      };
    },
    // 编辑时
    editData(row) {
      this.resetData(); //重置数据
      let {
        title,
        type,
        imgUrl,
        color,
        status,
        unionType,
        unionValue,
        id: adId,
      } = row; //获取行内信息
      let num = unionValue - 0; //转型
      unionValue = isNaN(num) ? unionValue : num; //判断是否是数字
      this.dialogFrom.color = color; //获取到颜色
      // 如果是无需图片的类型把它的默认图片删除
      if (type >= 6) imgUrl = "";
      Object.assign(this.dialogFrom, {
        title,
        type,
        imgUrl,
        color,
        status,
        unionType,
        unionValue,
        adId,
      });
      this.title = "修改";
      this.dialogShow = true;
    },
    // 提交图片的函数
    progress(item) {
      let formData = new FormData();
      let file = item.raw;
      formData.append("file", file);
      upload(formData).then((res) => {
        if (200 == res?.errno) {
          this.dialogFrom.imgUrl = res.url; //储存路径到表单
          colorImg(res.url, (color) => {
            this.dialogFrom.color = color;
          });
        }
      });
    },
    // 提交表单数据
    submitForm(formEl) {
      this.$refs[formEl].validate((valid) => {
        if (valid) {
          let data = {};
          Object.assign(data, this.dialogFrom);
          data.imgUrl = this.showImg
            ? data.imgUrl
            : "https://www.baidu.com/img/flexible/logo/pc/result.png"; //不需要图片添加默认图片
          data._mt = this.title == "创建" ? "create" : "edit"; //判断是编辑还是添加
          post(data).then((res) => {
            if (200 == res.errno) {
              this.dialogShow = false; //关闭弹窗
              ElMessage.success(this.title + "成功");
              this.initData(); //刷新数据
            }
          });
        }
      });
    },
  },
  created() {
    this.initData();
  },
  computed: {
    // 判断表单中的类型是否需要图片
    showImg() {
      return this.options.type.find(
        (item) => this.dialogFrom.type == item.value
      )?.picRequire;
    },
  },
  watch: {
    //弹出框是否显示
    dialogShow(n) {
      if (this.categorytList.length != 0) return; //长度不为0时获取树
      if (n) this.getTree();
    },
  },
};
</script>

<style scoped>
.el-header {
  height: auto;
  margin-bottom: 20px;
}
.el-form {
  display: flex;
  flex-wrap: wrap;
  width: 70%;
  margin-left: 15%;
}
.el-form-item {
  width: 100%;
}
.el-icon.avatar-uploader-icon {
  border-radius: 6px;
  border: 1px dashed var(--el-border-color);
  font-size: 28px;
  color: #8c939d;
  width: 150px;
  height: 150px;
  text-align: center;
}
</style>
